/*
 * Licensed to Nanjing RedOrange Co. ltd (RedOrange) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * RedOrange licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
package redora.rdo.generator;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.logging.Logger;

import com.sun.codemodel.CodeWriter;
import com.sun.codemodel.JCodeModel;
import com.sun.codemodel.writer.FileCodeWriter;
import com.sun.tools.xjc.BadCommandLineException;
import com.sun.tools.xjc.ConsoleErrorReporter;
import com.sun.tools.xjc.ErrorReceiver;
import com.sun.tools.xjc.Language;
import com.sun.tools.xjc.ModelLoader;
import com.sun.tools.xjc.Options;
import com.sun.tools.xjc.model.Model;
import com.sun.tools.xjc.outline.Outline;


public class JAXBGenerator {
	private static Logger l = Logger.getLogger("redora.rdo.generator.JAXBGenerator");
	
	private File targetDirectory;

	private Collection<File> schemas;
	
	private String targetPackage;

	public JAXBGenerator(Collection<File> schemas, File targetDirectory, String targetPackage) {
		this.schemas = schemas;
		this.targetDirectory = targetDirectory;
		this.targetPackage = targetPackage;
	}

	public Options createOptions() throws IOException, BadCommandLineException {
		Options options = new Options();
		options.targetDir = targetDirectory;
		options.verbose = true;
		options.debugMode = false;
		options.setSchemaLanguage(Language.XMLSCHEMA);
		options.strictCheck = false;
		options.readOnly = false;
		options.compatibilityMode = Options.EXTENSION;
		options.defaultPackage = targetPackage;
		if (schemas != null) {
			for (File schema : schemas) {
				options.addGrammar(schema);
			}
		}
		//TODO add these options
		//options.classpaths.add(new File("jaxb2-basics-runtime-0.5.2.jar").toURI().toURL());
		//for (Plugin p : options.getAllPlugins()) 
		//	l.info(p.getOptionName() + "/" + p.getUsage());
		//options.parseArguments(new String[]{"-Xequals", "-XhashCode", "-XtoString"});
		return options;
	}

	public void execute() throws IOException, BadCommandLineException {
		Options options = createOptions();
		JCodeModel codeModel = new JCodeModel();
		CodeWriter codeWriter = new FileCodeWriter(targetDirectory, false);
		ErrorReceiver errorReceiver = new ConsoleErrorReporter();
		execute(options, codeModel, codeWriter, errorReceiver);
	}
	
	protected void execute(Options options, JCodeModel codeModel,
			CodeWriter codeWriter, ErrorReceiver errorReceiver)
			throws IOException {
		l.fine("Loading the model.");
		Model model = ModelLoader.load(options, codeModel, errorReceiver);
		l.fine("Generating the code.");
		Outline outline = model.generateCode(options, errorReceiver);
		l.fine("Writing the code.");
		model.codeModel.build(codeWriter);
	}
}
